package com.eduagent.xwqeduagent.app.agent;

import com.eduagent.xwqeduagent.constant.FileConstant;
import com.eduagent.xwqeduagent.model.vo.OnlineSearchResultVO;
import com.eduagent.xwqeduagent.model.vo.SearchResultItemVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.regex.Pattern;

@Slf4j
@Component
public class OnlineSearch {

    /**
     * 联网搜索（返回JSON字符串）
     * @param content 搜索内容
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return JSON格式的搜索结果
     */
    public String onlineSearch(String content, String userId, String sessionId){
        try {
            OnlineSearchResultVO onlineSearchResultVO = performOnlineSearch(content, userId, sessionId);
            
            // 将结果转换为JSON字符串
            return cn.hutool.json.JSONUtil.toJsonStr(onlineSearchResultVO);
        } catch (Exception e) {
            log.error("联网搜索转换JSON失败", e);
            
            // 返回错误信息的JSON格式
            OnlineSearchResultVO errorResult = OnlineSearchResultVO.builder()
                    .status("error")
                    .message("联网搜索失败：" + e.getMessage())
                    .searchContent(content)
                    .sessionId(sessionId)
                    .searchTime(new Date())
                    .build();
            
            return cn.hutool.json.JSONUtil.toJsonStr(errorResult);
        }
    }

    /**
     * 联网搜索
     * @param content 搜索内容
     * @param userId 用户ID
     * @param sessionId 会话ID
     * @return 联网搜索结果
     */
    public OnlineSearchResultVO performOnlineSearch(String content, String userId, String sessionId) {
        log.info("开始联网搜索，内容：{}，用户ID：{}", content, userId);

        // Coze API配置
        String cozeApiUrl = "https://api.coze.cn/v3/chat";
        String botId = "7507539189127249932"; // 请替换为实际的联网搜索botId
        String apiKey = "pat_qm2xo8JAVOw7DGJcgmbpMTENCEst9IBcMt2xxRKig1RJLH9QBHDeEq6jgb2rKCxj"; // 请替换为实际的API密钥

        try {
            // 构建请求体
            cn.hutool.json.JSONObject requestBody = new cn.hutool.json.JSONObject();
            requestBody.set("bot_id", botId);
            requestBody.set("user_id", userId);
            requestBody.set("stream", false);
            requestBody.set("auto_save_history", true);

            // 构建消息内容
            cn.hutool.json.JSONArray additionalMessages = new cn.hutool.json.JSONArray();
            cn.hutool.json.JSONObject message = new cn.hutool.json.JSONObject();
            message.set("role", "user");
            message.set("content", "请帮我搜索以下内容并提供详细信息：" + content);
            message.set("content_type", "text");
            additionalMessages.add(message);

            requestBody.set("additional_messages", additionalMessages);

            // 设置请求头
            HashMap<String, String> headers = new HashMap<>();
            headers.put("Authorization", "Bearer " + apiKey);
            headers.put("Content-Type", "application/json");

            // 发送HTTP请求
            String result = cn.hutool.http.HttpUtil.createPost(cozeApiUrl)
                    .headerMap(headers, true)
                    .body(requestBody.toString())
                    .execute()
                    .body();

            log.info("联网搜索API响应：{}", result);

            // 解析响应
            cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

            // 检查状态
            if (responseJson.containsKey("data") && responseJson.getJSONObject("data").containsKey("status")) {
                String status = responseJson.getJSONObject("data").getStr("status");
                String conversationId = responseJson.getJSONObject("data").getStr("conversation_id");
                String chatId = responseJson.getJSONObject("data").getStr("id");

                if ("in_progress".equals(status)) {
                    // 如果状态是"in_progress"，需要轮询获取结果
                    return pollForSearchResult(conversationId, botId, apiKey, chatId, content, sessionId);
                } else if ("completed".equals(status)) {
                    // 如果已完成，直接处理结果
                    return processSearchResult(responseJson, content, sessionId);
                } else {
                    // 其他状态处理
                    log.warn("联网搜索状态未知：{}", status);
                    return OnlineSearchResultVO.builder()
                            .status("error")
                            .message("联网搜索状态未知: " + status)
                            .searchContent(content)
                            .sessionId(sessionId)
                            .searchTime(new Date())
                            .build();
                }
            } else {
                // 保存原始响应
                String searchPath = FileConstant.FILE_SAVE_DIR + "/searches/" + sessionId + "_search_raw.json";
                cn.hutool.core.io.FileUtil.mkdir(FileConstant.FILE_SAVE_DIR + "/searches/");
                cn.hutool.core.io.FileUtil.writeString(result, searchPath, "UTF-8");

                return OnlineSearchResultVO.builder()
                        .status("error")
                        .message("联网搜索请求已提交，但响应格式不符合预期，已保存原始响应")
                        .searchContent(content)
                        .sessionId(sessionId)
                        .filePath(searchPath)
                        .searchTime(new Date())
                        .build();
            }
        } catch (Exception e) {
            log.error("联网搜索失败", e);

            return OnlineSearchResultVO.builder()
                    .status("error")
                    .message("联网搜索失败：" + e.getMessage())
                    .searchContent(content)
                    .sessionId(sessionId)
                    .searchTime(new Date())
                    .build();
        }
    }

    /**
     * 轮询获取联网搜索结果
     */
    private OnlineSearchResultVO pollForSearchResult(String conversationId, String botId, String apiKey, 
                                                   String chatId, String searchContent, String sessionId) {
        // 构造API地址
        String checkStatusUrl = "https://api.coze.cn/v3/chat/message/list?" +
                "chat_id=" + chatId +
                "&conversation_id=" + conversationId;

        // 请求头配置
        HashMap<String, String> headers = new HashMap<>();
        headers.put("Authorization", "Bearer " + apiKey);
        headers.put("Content-Type", "application/json");

        // 最多尝试20次，每次间隔3秒
        for (int i = 0; i < 20; i++) {
            try {
                Thread.sleep(3000);
                String result = cn.hutool.http.HttpUtil.createGet(checkStatusUrl)
                        .headerMap(headers, true)
                        .execute()
                        .body();

                cn.hutool.json.JSONObject responseJson = new cn.hutool.json.JSONObject(result);

                // 检查响应状态码
                if (responseJson.getInt("code") == 0 && responseJson.containsKey("data")) {
                    // 获取消息列表
                    cn.hutool.json.JSONArray messages = responseJson.getJSONArray("data");

                    // 遍历消息找到assistant的回复或tool_response
                    for (int j = 0; j < messages.size(); j++) {
                        cn.hutool.json.JSONObject message = messages.getJSONObject(j);
                        String messageType = message.getStr("type");
                        String role = message.getStr("role");
                        
                        if ("assistant".equals(role) && "answer".equals(messageType)) {
                            String content = message.getStr("content");
                            if (cn.hutool.core.util.StrUtil.isNotBlank(content)) {
                                // 找到了搜索结果
                                return processSearchResult(message, searchContent, sessionId);
                            }
                        }
                    }

                    // 如果找不到结果，继续轮询
                    log.info("联网搜索进行中，继续等待... (第{}次尝试)", i + 1);
                } else {
                    log.warn("联网搜索失败，响应异常：{}", result);

                    return OnlineSearchResultVO.builder()
                            .status("error")
                            .message("联网搜索失败，请检查响应状态")
                            .searchContent(searchContent)
                            .sessionId(sessionId)
                            .searchTime(new Date())
                            .build();
                }
            } catch (Exception e) {
                log.error("轮询联网搜索状态失败", e);
            }
        }

        return OnlineSearchResultVO.builder()
                .status("error")
                .message("联网搜索超时，请稍后重试")
                .searchContent(searchContent)
                .sessionId(sessionId)
                .searchTime(new Date())
                .build();
    }

    /**
     * 处理联网搜索结果
     * @param messageJson 消息JSON对象
     * @param searchContent 搜索内容
     * @param sessionId 会话ID
     * @return 搜索结果
     */
    private OnlineSearchResultVO processSearchResult(cn.hutool.json.JSONObject messageJson, 
                                                   String searchContent, String sessionId) {
        try {
            // 1. 从消息中提取content字段
            String content = messageJson.getStr("content");
            if (cn.hutool.core.util.StrUtil.isBlank(content)) {
                throw new IllegalArgumentException("消息中缺少content字段");
            }

            // 3. 解析结构化搜索结果
            List<SearchResultItemVO> searchItems = parseStructuredResults(content);


            // 5. 构建存储路径
            String fileName = sessionId + "_search_result.json";
            String saveDir = FileConstant.FILE_SAVE_DIR + "/searches/";

            // 确保目录存在
            cn.hutool.core.io.FileUtil.mkdir(saveDir);
            String filePath = saveDir + fileName;

            // 6. 创建结构化的搜索结果数据
            cn.hutool.json.JSONObject searchData = new cn.hutool.json.JSONObject();
            searchData.put("search_content", searchContent);
            searchData.put("search_result", content);
            searchData.put("search_items", searchItems);
            searchData.put("result_count", searchItems.size());
            searchData.put("session_id", sessionId);
            searchData.put("search_time", new Date());
            searchData.put("raw_message", messageJson);

            // 7. 保存文件
            cn.hutool.core.io.FileUtil.writeUtf8String(searchData.toString(), filePath);

            // 8. 构建返回结果
            return OnlineSearchResultVO.builder()
                    .status("success")
                    .message("联网搜索完成")
                    .searchContent(searchContent)
                    .searchResult(content)
                    .searchItems(searchItems)
                    .resultCount(searchItems.size())
                    .filePath(filePath)
                    .sessionId(sessionId)
                    .searchTime(new Date())
                    .build();
        } catch (Exception e) {
            // 9. 异常处理
            String errorMessage = "处理联网搜索结果失败";
            if (e instanceof IllegalArgumentException) {
                log.warn("{}：{}", errorMessage, e.getMessage());
                return OnlineSearchResultVO.builder()
                        .status("error")
                        .message(errorMessage + "：" + e.getMessage())
                        .searchContent(searchContent)
                        .sessionId(sessionId)
                        .searchTime(new Date())
                        .build();
            } else {
                log.error(errorMessage, e);
                return OnlineSearchResultVO.builder()
                        .status("error")
                        .message(errorMessage + "：" + e.getClass().getSimpleName())
                        .searchContent(searchContent)
                        .sessionId(sessionId)
                        .searchTime(new Date())
                        .build();
            }
        }
    }

    /**
     * 解析结构化搜索结果
     * @param content 搜索结果内容
     * @return 结构化搜索结果列表
     */
    private List<SearchResultItemVO> parseStructuredResults(String content) {
        List<SearchResultItemVO> searchItems = new ArrayList<>();
        
        // 匹配编号列表格式的搜索结果，如：1. **来源网站**：描述，链接为[链接文本](URL)
        Pattern itemPattern = Pattern.compile("(\\d+)\\s*\\.\\s*\\*\\*([^*]+)\\*\\*[：:]([^，。]+)[，。]*(?:链接为)?\\[([^\\]]+)\\]\\(([^)]+)\\)");
        java.util.regex.Matcher matcher = itemPattern.matcher(content);
        
        while (matcher.find()) {
            SearchResultItemVO item = SearchResultItemVO.builder()
                    .index(Integer.parseInt(matcher.group(1)))
                    .sourceName(matcher.group(2).trim())
                    .description(matcher.group(3).trim())
                    .linkText(matcher.group(4).trim())
                    .url(matcher.group(5).trim())
                    .build();
            searchItems.add(item);
        }
        
        // 如果没有匹配到结构化格式，尝试其他格式
        if (searchItems.isEmpty()) {
            searchItems = parseAlternativeFormat(content);
        }
        
        return searchItems;
    }

    /**
     * 解析其他格式的搜索结果
     * @param content 搜索结果内容
     * @return 结构化搜索结果列表
     */
    private List<SearchResultItemVO> parseAlternativeFormat(String content) {
        List<SearchResultItemVO> searchItems = new ArrayList<>();
        
        // 尝试匹配简单的链接格式
        Pattern linkPattern = Pattern.compile("\\[([^\\]]+)\\]\\(([^)]+)\\)");
        java.util.regex.Matcher linkMatcher = linkPattern.matcher(content);
        
        int index = 1;
        while (linkMatcher.find()) {
            SearchResultItemVO item = SearchResultItemVO.builder()
                    .index(index++)
                    .linkText(linkMatcher.group(1).trim())
                    .url(linkMatcher.group(2).trim())
                    .description("链接：" + linkMatcher.group(1).trim())
                    .build();
            searchItems.add(item);
        }
        
        return searchItems;
    }

}
